package com.zwl.SpringBootAndroid.server;


import com.zwl.SpringBootAndroid.util.LogUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import io.netty.handler.codec.http.multipart.MemoryAttribute;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * http数据的处理
 *
 * @author 万祥新
 *
 */
public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    private String uri;

    public HttpRequestHandler(String uri) {
        this.uri = uri;
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        if (request.uri().indexOf(uri) != 0) {
            return;
        }

        Map<String, String> requestParams = new HashMap<>();

        if (request.method() == HttpMethod.GET) {
            QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
            Map<String, List<String>> params = decoder.parameters();
            for (Entry<String, List<String>> next : params.entrySet()) {
                requestParams.put(next.getKey(), next.getValue().get(0));
            }
        } else if (request.method() == HttpMethod.POST) {
            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), request);
            List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
            for (InterfaceHttpData data : postData) {
                if (data.getHttpDataType() == HttpDataType.Attribute) {
                    MemoryAttribute attribute = (MemoryAttribute) data;
                    requestParams.put(attribute.getName(), attribute.getValue());
                }
            }
        }
        FullHttpResponse httpResponse;
        String responseContent;
        String action = requestParams.get("action");
        if (action == null) {
            action = "";
        }
        if (action.equals("closeAll")) {
            // 通过http后台关闭所有连接
            int closeSize = SocketChannelHandler.closeAll();
            responseContent = ResponseJsonUtil.genSuccessData(String.format("已经断开所有连接%s个", closeSize));
        } else if (action.equals("sendAll")) {
            // 通过http后台给所有用户发送消息
            String content = requestParams.get("content");
            int size = SocketChannelHandler.broadcastToAll(content);
            responseContent = ResponseJsonUtil.genSuccessData(String.format("广播%s到了%d用户", content, size));
            LogUtil.log("通过http后台给所有用户发送消息"+responseContent);
        } else if (action.equals("push")){
            // 通过http后台给用户发送消息
            String content = requestParams.get("content");
            String to = requestParams.get("to");
            boolean isSuccess = SocketChannelHandler.broadcastToClientId(to, content);
            responseContent = ResponseJsonUtil.genSuccessData(String.format("广播%s给%s设备>>%s", content, to, isSuccess));
            LogUtil.log(String.format("通过http后台给 %s 设备发送消息>>>%s", to, responseContent));
        } else {
            //默认查询当前连接信息
            responseContent = ResponseJsonUtil.genSuccessData(SocketChannelHandler.getConnectInfo());
            LogUtil.log("查询连接信息>>" + responseContent);
        }
        if (responseContent == null) {
            ResponseJsonUtil.genFailData(500, "错误的查询");
        }
        httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
                Unpooled.wrappedBuffer(responseContent.getBytes(StandardCharsets.UTF_8)));
        httpResponse.headers().set("Content-Type", "application/json; UTF_8");
        httpResponse.headers().set("Content-Length", httpResponse.content().readableBytes());
        ctx.writeAndFlush(httpResponse);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}